const chalk = require('chalk');
const { copy, ensureDir, remove } = require('fs-extra');
const path = require('path');
const { execSync } = require('child_process');

const sourceAppsPath = path.resolve(__dirname, '../apps');
const targetPath = path.resolve(__dirname, '../../ai-plat-web-build');
const TARGET_BRANCH = 'test';

// 定义需要复制的项目及其构建目录
const projectMap = {
  main: {
    buildDir: 'kbs',
    targetDir: 'kbs',
  },
  'micro-agent': {
    buildDir: 'micro-agent',
    targetDir: 'micro-agent',
  },
  'micro-bi': {
    buildDir: 'micro-bi',
    targetDir: 'micro-bi',
  },
  'micro-business': {
    buildDir: 'micro-business',
    targetDir: 'micro-business',
  },
  'micro-chat': {
    buildDir: 'micro-chat',
    targetDir: 'micro-chat',
  },
  'micro-execute': {
    buildDir: 'micro-execute',
    targetDir: 'micro-execute',
  },
  'micro-knowledge': {
    buildDir: 'micro-knowledge',
    targetDir: 'micro-knowledge',
  },
  'micro-plugins': {
    buildDir: 'micro-plugins',
    targetDir: 'micro-plugins',
  },
  'micro-tips': {
    buildDir: 'micro-tips',
    targetDir: 'micro-tips',
  },
  'micro-workflow': {
    buildDir: 'micro-workflow',
    targetDir: 'micro-workflow',
  },
  'micro-newbi': {
    buildDir: 'micro-cqtelebi.tar',
    targetDir: 'micro-cqtelebi.tar',
  },
};

// 错误处理工具函数
function getErrorMessage(error) {
  if (error instanceof Error) return error.message;
  return String(error);
}

// 执行 git 命令
function execGitCommand(command, cwd) {
  try {
    execSync(command, { cwd, stdio: 'inherit' });
    return true;
  } catch (err) {
    console.error(chalk.red(`执行git命令失败: ${getErrorMessage(err)}`));
    return false;
  }
}

async function deployTest() {
  try {
    console.log(chalk.blue('开始部署测试环境...'));

    // 确保目标目录存在
    await ensureDir(targetPath);

    // 切换到目标目录并拉取最新代码
    console.log(chalk.yellow('正在拉取远程代码...'));

    // 检查是否有未提交的更改
    if (!execGitCommand('git status --porcelain', targetPath)) {
      console.error(chalk.red('检查git状态失败，请确保目标仓库状态正常'));
      process.exit(1);
    }

    // 如果有未提交的更改，提示用户
    const hasChanges = execSync('git status --porcelain', { cwd: targetPath }).toString().trim();
    if (hasChanges) {
      console.error(chalk.red('目标仓库有未提交的更改，请先处理这些更改'));
      process.exit(1);
    }

    // 获取当前分支
    const currentBranch = execSync('git rev-parse --abbrev-ref HEAD', { cwd: targetPath }).toString().trim();

    // 如果不在目标分支上，切换分支
    if (currentBranch !== TARGET_BRANCH) {
      console.log(chalk.yellow(`切换到 ${TARGET_BRANCH} 分支...`));

      // 检查本地是否有test分支
      const localBranches = execSync('git branch', { cwd: targetPath })
        .toString()
        .split('\n')
        .map((b) => b.trim().replace('* ', ''))
        .filter(Boolean);

      if (!localBranches.includes(TARGET_BRANCH)) {
        // 如果本地没有test分支，从远程拉取并切换
        if (!execGitCommand(`git fetch origin ${TARGET_BRANCH}:${TARGET_BRANCH}`, targetPath)) {
          console.error(chalk.red(`拉取 ${TARGET_BRANCH} 分支失败`));
          process.exit(1);
        }
      }

      // 切换到test分支
      if (!execGitCommand(`git checkout ${TARGET_BRANCH}`, targetPath)) {
        console.error(chalk.red(`切换到 ${TARGET_BRANCH} 分支失败`));
        process.exit(1);
      }
    }

    // 拉取最新代码
    if (!execGitCommand('git pull', targetPath)) {
      console.error(chalk.red('拉取远程代码失败'));
      process.exit(1);
    }

    // 遍历处理每个项目
    for (const [project, config] of Object.entries(projectMap)) {
      try {
        const sourcePath = path.join(sourceAppsPath, project, config.buildDir);
        const targetFilePath = path.join(targetPath, config.targetDir);

        // 删除目标路径中已存在的文件/目录
        console.log(chalk.yellow(`正在删除旧文件: ${config.targetDir}`));
        await remove(targetFilePath);

        // 复制新文件
        console.log(chalk.yellow(`正在复制: ${project} -> ${config.targetDir}`));
        await copy(sourcePath, targetFilePath);

        console.log(chalk.green(`✓ ${project} 部署成功`));
      } catch (err) {
        console.error(chalk.red(`× ${project} 部署失败: ${getErrorMessage(err)}`));
      }
    }

    console.log(chalk.green('\n部署完成!'));
  } catch (err) {
    console.error(chalk.red(`部署过程出错: ${getErrorMessage(err)}`));
    process.exit(1);
  }
}

deployTest();
